extends CanvasLayer

var world_states = {}
const SAVE_PATH := "user://user_data.sav"
const CONFIG_PATH:="user://config.ini"

@onready var player_blackboard: PlayerBlackBoard = $PlayerBlackBoard
@onready var color_rect: ColorRect = $ColorRect
@onready var game_over: Control = $GameOver
@onready var pause_scene: Control = $PauseScene

signal camera_should_shake(amount:float)

func _ready():
	color_rect.color.a = 0
	load_config()
	
func change_scene(path:String, entry_point:Vector2, direction:int) -> void:
	var tree:= get_tree()
	tree.paused = true
	await _transition_start()
	
	# 存储当前场景信息
	if tree.current_scene is World:
		_save_current_scene(tree)
	tree.change_scene_to_file(path)
	await tree.tree_changed
	
	# 恢复场景信息
	if tree.current_scene is World:
		_load_current_scene(tree)
		tree.current_scene.update_player(entry_point, direction)
	
	tree.paused = false
	await _transition_end()
	
func change_scene_title(path:String) -> void:
	var tree:= get_tree()
	tree.paused = true
	await _transition_start()
	
	# 存储当前场景信息
	tree.change_scene_to_file(path)
	await tree.tree_changed

	tree.paused = false
	await _transition_end()
	
func _get_current_scene(tree: SceneTree) -> Dictionary:
	return tree.current_scene.to_dict()

func _save_current_scene(tree:SceneTree) -> void:
	var old_name := _get_scene_basename(tree)
	world_states[old_name] = _get_current_scene(tree)
	
func _load_current_scene(tree:SceneTree):
	var new_name := _get_scene_basename(tree)
	if new_name in world_states:
		tree.current_scene.from_dict(world_states[new_name])
		
# 获取当前场景树
func _get_scene_basename(tree:SceneTree)->String:
	return tree.current_scene.scene_file_path.get_file().get_basename()

func _transition_start():
	var tween := create_tween()
	tween.set_pause_mode(Tween.TWEEN_PAUSE_PROCESS)
	tween.tween_property(color_rect, "color:a", 1, 0.2)
	await tween.finished
	
func _transition_end():
	var tween = create_tween()
	tween.tween_property(color_rect, "color:a", 0, 0.2)
	await tween.finished

func reload_scene() -> void:
	player_blackboard.get_stats().reset()
	get_tree().reload_current_scene()

# 保存游戏与加载游戏
func save_game() -> void:
	var tree := get_tree()
	_save_current_scene(tree)
	var data:={
		world_states = world_states, # 场景信息的保存
		player_states = player_blackboard.to_dict(),
		scene = tree.current_scene.scene_file_path, # 当前场景信息
	}
	var json := JSON.stringify(data)
	var file = FileAccess.open(SAVE_PATH,FileAccess.WRITE)
	if not file:
		print("can't save game")
		return 
	file.store_line(json)
	
func load_game() -> void:
	var file = FileAccess.open(SAVE_PATH,FileAccess.READ)
	if not file:
		print("can't load game")
		return 
	var json := file.get_as_text()
	var data = JSON.parse_string(json) as Dictionary
	
	world_states = data.world_states
	var player_states = data.player_states
	player_blackboard.from_dict(player_states)
	
	var pos = Vector2(player_states.position.x, player_states.position.y)
	change_scene(data.scene, pos, player_states.direction )

func new_game() -> void:
	world_states = {}
	change_scene(
		"res://world01.tscn", 
		 Vector2(270,160), 
		1
	)
		
func back_to_title() -> void:
	world_states = {}
	change_scene_title(
		"res://ui/title_screen.tscn"
	)

func has_save() -> bool:
	return FileAccess.file_exists(SAVE_PATH)

func to_game_over():
	game_over.show_game_over()

func to_game_end():
	change_scene_title(
		"res://ui/game_end.tscn"
	)
func to_game_pause():
	pause_scene.show_pause()
#
## 游戏保存
func save_config():
	var file = ConfigFile.new()
	file.set_value("audio","master", SoundManager.get_volume(SoundManager.Bus.MASTER))
	file.set_value("audio","bgm", SoundManager.get_volume(SoundManager.Bus.BGM))
	file.set_value("audio","sfx", SoundManager.get_volume(SoundManager.Bus.SFX))

	var err = file.save(CONFIG_PATH)
	if err!=OK:
		push_error("failed to save config:%d", err)
		
# 游戏加载
func load_config():
	var file = ConfigFile.new()
	var err = file.load(CONFIG_PATH)

	SoundManager.set_volume(
		SoundManager.Bus.MASTER,
		file.get_value("audio","master", 1.0)
	)
	SoundManager.set_volume(
		SoundManager.Bus.BGM,
		file.get_value("audio","bgm", 1.0)
	)
	SoundManager.set_volume(
		SoundManager.Bus.SFX,
		file.get_value("audio","sfx", 1.0)
	)

		##push_warning("failed to load config:%d",err)
func shake_camera(amount:float) -> void:
	camera_should_shake.emit(amount)

# hit stop 函数
func _hit_stop(time:float,begin:float = 0.0, end:float = 1.0) ->void:
	Engine.time_scale = begin
	await get_tree().create_timer(time, true, false, true).timeout
	Engine.time_scale = end
	
func hit_stop_short()->void:
	_hit_stop(0.15)
	
func hit_stop_medium()->void:
	_hit_stop(0.25)

func hit_stop_long()->void:
	_hit_stop(0.5)
# 慢放
func slow_motion_short()->void:
	_hit_stop(0.5,0.5)
